using UnityEngine;

namespace IQIGame.Onigao.GamePlay
{
    public class SmallPetCircleMoveBehavior : SmallPetBaseMoveBehavior
    {

        private float _curRadiusXZ;

        private float _startRadiusXZ;

        private float _endRadiusXZ;

        //y分量范围
        private float _startY;

        private float _endY;

        private float _angleSpeed;

        private float _passedTime;

        private float _totalTime;

        private float _angle;

        private static readonly float _minY = 0f;
        private static readonly float _maxY = ViewEntityConst.CharacterHeight * 0.5f;
        private const float CircleAngle = 360f;

        private Vector3 _curOffset;
        private Vector3 _forward;
        //最大半径范围
        public float maxRadiusXZ { get; set; }

        public override void OnUpdate(float dt)
        {
            _passedTime += dt;
            _angle += dt * _angleSpeed * Mathf.Deg2Rad;
            var prevOffset = _curOffset;
            _curOffset = CalculateOffset();
            _forward = _curOffset - prevOffset;
            if (GameScenePlayUtil.IsPlayerMoving()) return;
            entity.transform.forward = _forward;
            entity.transform.position = entity.owner.transform.position + _curOffset;
            if (_passedTime >= _totalTime)
            {
                InitCircleParameters();
            }
        }

        public override uint MaxStore => 20;

        public override void OnReset()
        {
            base.OnReset();
            _startY = 0f;
            _endY = 0f;
            _startRadiusXZ = 0f;
            _endRadiusXZ = 0f;
            _totalTime = 0f;
            _passedTime = 0f;
            _angleSpeed = 0f;
            maxRadiusXZ = 0f;
            _angle = 0f;
            entity = null;
            _curOffset = Vector3.zero;
            _forward = Vector3.zero;
        }

        private Vector3 CalculateOffset()
        {
            var t = _passedTime / _totalTime;
            var targetY = Mathf.Lerp(_startY, _endY, t);
            var radiusXZ = Mathf.Lerp(_startRadiusXZ, _endRadiusXZ, t);
            var k = Mathf.Tan(_angle);
            // x² + k²x² = radiusXZ²;
            var curX = _curOffset.x;
            var curZ = _curOffset.z;
            var x1 = Mathf.Sqrt(radiusXZ * radiusXZ / (k * k + 1));
            var x2 = -Mathf.Sqrt(radiusXZ * radiusXZ / (k * k + 1));
            var disSquare1 = (x1 - curX) * (x1 - curX) + (k * x1 - curZ) * (k * x1 - curZ);
            var disSquare2 = (x2 - curX) * (x2 - curX) + (k * x2 - curZ) * (k * x2 - curZ);
            var targetX = disSquare1 < disSquare2 ? x1 : x2;
            return new Vector3(targetX, targetY, k * targetX);
        }

        public void InitCircleParameters()
        {
            _passedTime = 0;
            _startY = entity.transform.position.y - entity.owner.transform.position.y;
            _endY = Random.Range(_minY, _maxY);
            var curPosXZ = new Vector2(entity.transform.position.x, entity.transform.position.z);
            var centerXZ = new Vector2(entity.owner.transform.position.x, entity.owner.transform.position.z);
            _startRadiusXZ = Vector2.Distance(curPosXZ, centerXZ);
            //可以控制_endRadiusXZ来调整移动范围
            _endRadiusXZ = maxRadiusXZ;
            //可以通过控制_angleSpeed来调整旋转方向和速度
            //var dir = Random.Range(0, 2);
            _angleSpeed = 90; //dir == 0 ? -60 : 60;
            _totalTime = Mathf.Abs(CircleAngle / _angleSpeed);
        }

        //同一帧内 OnOwnerMove 在 OnUpdate 之后调用
        //因此需要在OnOwnerMove时再次更新位置以防止抖动
        public override void OnOwnerMove(Vector3 pos, float power)
        {
            entity.transform.forward = _forward;
            entity.transform.position = pos + _curOffset;

            if (_passedTime >= _totalTime)
            {
                InitCircleParameters();
            }
        }
    }
}